package com.hzjq.core.worker

import android.text.TextUtils
import com.hzjq.core.BlastDelegate
import com.hzjq.core.ErrorCode
import com.hzjq.core.bean.CapEntity
import com.hzjq.core.bean.ErrorCapEntity
import com.hzjq.core.bean.ErrorReadCapEntity
import com.hzjq.core.callback.Callback
import com.hzjq.core.massage.DataMessageBean
import com.hzjq.core.receive.Receiver
import com.hzjq.core.receive.Receives
import com.hzjq.core.work.Work

abstract class ErrorReadWork : Work<ErrorReadCapEntity> {

    private var progress = 0

    private var count = 0

    private val errors = arrayListOf<ErrorCapEntity>()

    private var totalCapCount = 0

    private var currentCapCount = 0

    private var readEndFlag = false

    private val mErrorReadCapEntity = ErrorReadCapEntity()

    constructor(callback: Callback<ErrorReadCapEntity>?) : super(callback)

    override fun doWork(vararg args: Any) {
        BlastDelegate.getDelegate().post(Runnable {
                onProgressChanged(50 + progress, "正在读取错误雷管信息")
            }
        )

        if (totalCapCount == 0) {
            totalCapCount = BlastDelegate.getDelegate().getMaxSupportCapCount()
        }
        if(args.size > 1){
            count = args[1] as Int
        }

        var position = count
        if (count > totalCapCount) {
            position = count - 16
        }
        if(position - 16 > totalCapCount){
            readEndFlag = true
            return
        }

        Receives.getInstance()
            .registerReceiver(
                BlastDelegate.getDelegate().getAssemblyCmdLoader().getReadCapCmd(position),
                object : Receiver {
                    override fun convert(msg: String): Any {
                        if (msg.length > 40) {
                            if(!readEndFlag) {
                                checkCapRetry(msg)
                            }
                            return BlastDelegate.getDelegate().getParseLoader()
                                .parseCap(msg)
                        }
                        return msg
                    }

                    override fun onSuccess(msg: Any) {
                        if (msg is MutableList<*>) {
                            checkMaxLimitCap(msg as MutableList<CapEntity>)
                        } else {
                            onProgressChanged(100, "读取错误雷管信息失败")
                            callback?.onError(ErrorCode.getErrorResult(-15))
                            onDestroy()
                        }
                    }

                    override fun failed() {
                        onProgressChanged(100, "读取错误雷管信息失败")
                        callback?.onError(ErrorCode.getErrorResult(-16))
                        onDestroy()
                    }

                })
        val msg = DataMessageBean(
            BlastDelegate.getDelegate().getAssemblyCmdLoader().getReadCapCmd(count).cmd
        )
        BlastDelegate.getDelegate().getCmdExeLoader().exePollResultCmd(msg.assembly(), callback)

    }

    private fun checkCapRetry(msg: String) {
        val total = Integer.valueOf(msg.substring(16, 20), 16)
        totalCapCount = total
        readEndFlag = count + 16 >= total
        if (count < total) {
            doWork(totalCapCount,count + 16)
        }
    }

    private fun checkMaxLimitCap(caps: MutableList<CapEntity>) {

        caps.forEach {
            val checkCapError = checkCapError(it)
            if (checkCapError != null && !contains(checkCapError)) {
                mErrorReadCapEntity.errors.add(checkCapError)
            }
        }

        mErrorReadCapEntity.caps.addAll(caps)

        if (currentCapCount + caps.size >= totalCapCount) {
            onProgressChanged(100, "已读取全部错误雷管信息")
            checkNotMatchCap()
            onDestroy()
        } else {
            currentCapCount += caps.size
            progress =
                ((currentCapCount + 1) * ((100.0f - 50.toFloat()) / totalCapCount.toFloat())).toInt()
            callback?.onResult(mErrorReadCapEntity)
        }
    }

    private fun checkNotMatchCap() {
        if(mErrorReadCapEntity.caps.isNotEmpty()){
            mErrorReadCapEntity.caps[mErrorReadCapEntity.caps.size -1].isScanEnd = true
        }
        if (errors.isNotEmpty()) {
            errors[errors.size - 1].cap!!.isScanEnd = true
        }
        callback?.onResult(mErrorReadCapEntity)
    }


    fun contains(cap: ErrorCapEntity): Boolean {
        if (errors.isNotEmpty()) {
            errors.forEach {
                if (TextUtils.equals(cap.cap!!.uid, it.cap!!.uid)) {
                    return true
                }
            }
        }
        return false
    }


    abstract fun checkCapError(cap: CapEntity): ErrorCapEntity?


    override fun cancel() {
        errors.clear()
        count = 0
        Receives.getInstance()
            .unRegisterReceiver(
                BlastDelegate.getDelegate().getAssemblyCmdLoader().getReadCapCmd(count)
            )
    }
}